/*
 *  Copyright (C) 2011 JiangHongTiao <jjurco.sk_gmail.com>
 * 
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 * 
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 * 
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
package sk.lieskove.jianghongtiao.sitesearch.plugin;

import com.hp.hpl.jena.rdf.model.Resource;
import org.apache.log4j.Logger;
import sk.lieskove.jianghongtiao.common.utils.PropertiesUtils;
import sk.lieskove.jianghongtiao.multithreaddownloader.MultiThreadDownloadManager;
import sk.lieskove.jianghongtiao.multithreaddownloader.MultiThreadDownloader;
import sk.lieskove.jianghongtiao.multithreaddownloader.request.PageRequestBuilder;
import sk.lieskove.jianghongtiao.sitesearch.documents.Validators;

import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
import javax.xml.validation.Validator;
import java.io.File;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;

/**
 * Date of create: Sep 14, 2011
 *
 * @author JiangHongTiao <jjurco.sk_gmail.com>
 * @version 2011.0914
 */
public abstract class AbstractPlugin extends PageRequestBuilder
        implements SiteResourcesPlugin {

    private Logger log = Logger.getLogger(this.getClass().getName());
    private int maxLimitSize = 1000;
    protected static Transformer transformer = null;
    private static Validator validator =
            Validators.getInstanceOfSearchResultValidator();
    private String name = "default";
    private PropertiesUtils properties = null;
    private MultiThreadDownloadManager downloader = MultiThreadDownloader.getInstance();

//    
//    /**
//     * From the actual page with results retrieve link to next page with results.
//     * 
//     * @param pageSource source code of actual page to be parsed.
//     * @return URL to next page with results, otherwise <code>null</code>.
//     */
//    protected abstract URL getNextResultsLink(String pageSource);
    protected void setTransformer(File xsltTemplate) {
        try {
            transformer = TransformerFactory.newInstance().
                    newTransformer(new StreamSource(xsltTemplate));
        } catch (TransformerConfigurationException ex) {
            log.error("Transformer has bad configuration!");
        }
    }

    private String getProperty(String key) {
        return properties.getProperty("ssp-" + name + "-" + key);
    }

    private void initialize() throws FileNotFoundException {
        properties = new PropertiesUtils(this.getClass());
        Integer max = Integer.parseInt(getProperty("max-search-limit"));
        if ((max != null) && (max > 0)) {
            maxLimitSize = max;
        }
        //set transformer
        File searchResultTransformer =
                new File(getProperty("search-result-transformer"));
        if (searchResultTransformer.exists()) {
            setTransformer(searchResultTransformer);
        } else {
            log.error("Transformation file '" + searchResultTransformer.
                    getAbsolutePath() + "' does not exists!");
            throw new FileNotFoundException("Cannot initialize plugin. "
                    + "Transformation template was not found!");
        }
    }

    /**
     * Indicates the name for this plug-in. Based on this name this class will
     * read properties from the configuration file. Base name in configuration
     * file for every plug-in is "ssp-&lt;name&gt;-". All settings 
     * are read from this file. When no configuration or configuration file is 
     * found, default settings are used. At first, when configuration file is 
     * found but settings are missing, default settings in configuration file
     * are used. When no configuration file is found or no default settings are 
     * used, exception is thrown (expect those settings which can be derived
     * automatically). 
     * 
     * @param name the name of the plug-in
     */
    protected void setTransformerName(String name) throws FileNotFoundException {
        this.name = name;
        initialize();
    }
    
    public Resource search(int maxResults) {
        if (maxResults < 1) {
            throw new IllegalArgumentException("Max results is negative number.");
        }
        List<File> results = new ArrayList<File>();
        int numberOfResults = 0;
        try {
            //--results.add(getAnswer());
            
            transformer.transform(new StreamSource(),
                    new StreamResult(new File("")));               /////////////todo

            while (numberOfResults >= maxResults) {
                
            }
        } catch (TransformerException ex) {
            java.util.logging.Logger.getLogger(AbstractPlugin.class.getName()).
                    log(Level.SEVERE, null, ex);
        }
//        } catch (NotEnoughParametersException ex) {
//            java.util.logging.Logger.getLogger(AbstractPlugin.class.getName()).
//                    log(Level.SEVERE, null, ex);
//        }
        return null;
        /**
         * 1. stiahnut stranku s vysledkami hladania
         * 2. rozparsovat odkazy - transformovat na XML so strukturou SearchService.xsd
         * 3. zakial nebude dost odkazov podla limitu,
         *    alebo max. pocet vysledkov hladania
         */
    }

    public Resource search() {
        return search(getMaxLimitSize());
    }

    public int getMaxLimitSize() {
        return maxLimitSize;
    }

    protected void setMaxLimitSize(int limit) {
        if (limit < 1) {
            maxLimitSize = limit;
        }
    }
}
